<!--
 * @Description: ------------ fileDescription -----------
 * @Author: snows_l snows_l@163.com
 * @Date: 2024-08-13 13:13:23
 * @LastEditors: snows_l snows_l@163.com
 * @LastEditTime: 2025-11-05 15:52:56
 * @FilePath: \BLOG\src\components\common\CommentInput.vue
 * @Copyright © 2020-2024 snows_l. All rights reserved.
-->

<!--
 * @Description props说明
 * 数据双向绑定
 * modelValue: {
    value: '',
    qq: '',
    nickName: '',
    email: '',
    websiteUrl: '',
    isPrivacy: false,
    isEmailFeekback: false,
    submitLoading: false
  }
 *
-->
<template>
  <div class="comment-wrap" :class="{ 'm-comment-wrap': isMobi, 'is-submit': isSubmit }">
    <div class="top-tip">
      ⚠ 使用cookie技术保留您的个人信息以便您下次快速评论，继续评论表示您已同意该条款。
      <!-- <span v-if="localValue.nickName" style="font-size: 16px; color: var(--theme-light-color-1)">欢迎你：{{ localValue.nickName }}</span> -->
    </div>
    <div class="input-out-wrap">
      <div class="input-wrap" :class="{ 'no-input-wrap': !localValue.value }">
        <textarea type="textarea" :class="{ 'have-text': localValue.value }" class="input-text comment-value-inner" :rows="6" placeholder="" v-model="localValue.value" />
        <label class="input-label">你是我一生只会遇见一次的惊喜 ...</label>
      </div>
    </div>
    <div class="info-wrap">
      <div class="input qq-wrap" :class="{ 'no-qq': !localValue.qq }">
        <input type="text" v-model="localValue.qq" placeholder="QQ" @blur="handleGetInfoByQQ" />
        <label class="input-label">QQ 仅仅用于获取头像及昵称，请放心 「食」 用^ _ ^</label>
        <img class="avatar" :src="localValue.avatarUrl || defaultAvatar" />
      </div>
      <div class="input qq-wrap" :class="{ 'no-nick': !localValue.nickName }" :style="{ 'background-color': nickNameLoading ? '#f5f5f5' : 'transparent' }">
        <input type="text" :disabled="nickNameLoading" v-model="localValue.nickName" placeholder="昵称( * )" />
        <label class="input-label">昵称 ( * )</label>
        <img class="avatar" v-show="nickNameLoading" style="width: 28px; margin-right: 10px" src="@/assets/images/common/loading.svg" alt="" />
      </div>
      <div class="input email-wrap" :style="{ 'background-color': nickNameLoading ? '#f5f5f5' : 'transparent' }">
        <input type="text" :disabled="nickNameLoading" v-model="localValue.email" placeholder="邮箱 ( * )" />
        <label class="input-label">你将收到回复通知 (自动获取)</label>
        <img class="avatar" v-show="nickNameLoading" style="width: 28px; margin-right: 10px" src="@/assets/images/common/loading.svg" />
      </div>
      <div class="input url-wrap">
        <input type="text" v-model="localValue.websiteUrl" placeholder="网站" />
        <label class="input-label">禁止小广告 😀</label>
      </div>
    </div>
    <div class="check-wrap">
      <div class="check-item">
        <input type="checkbox" class="pointer" id="isEmailFeekback" v-model="localValue.isEmailFeekback" />
        <label class="pointer" for="isEmailFeekback">邮件通知</label>
      </div>

      <div class="check-item">
        <input type="checkbox" class="pointer" id="isPrivacy" checkedid="isPrivacy" v-model="localValue.isPrivacy" />
        <label class="pointer" for="isPrivacy">
          私密评论
          <span class="privacy-tip">（私密评论将不会展示在blog上）</span>
        </label>
      </div>
    </div>

    <div class="btn-wrap">
      <div class="btn" @click="handleSubmit">
        <img v-show="localValue.submitLoading" style="width: 28px; margin-right: 10px" src="@/assets/images/common/loading.svg" alt="" />
        <span>BiuBiuBiu~</span>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { getQQInfo } from '@/api/common';
import useResize from '@/hooks/useResize';
import { useAppStore } from '@/store/app';
import { getOnlineImgUrl, getQQAvatar, checkForbiddenWord, CustomMessage } from '@/utils/common';
import { computed, ref } from 'vue';
const store = useAppStore();

const { isMobi } = useResize();
const defaultAvatar = getOnlineImgUrl('avatar', '/imgs/common', 'png');
const emits = defineEmits(['submit', 'update:modelValue']);

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({
      value: '',
      qq: '',
      nickName: '',
      avatarUrl: '',
      email: '',
      websiteUrl: '',
      isPrivacy: false,
      isEmailFeekback: true,
      submitLoading: false
    })
  }
});

let isSubmit = ref(false);
let nickNameLoading = ref(false);

const localValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    emits('update:modelValue', value);
  }
});

//  更新 私密评论 和 邮件通知
// @change="e => update(e, 'isEmailFeekback')"
const update = (e, type) => {
  let n = { ...props.modelValue, [type]: e.target.checked };
  emits('update:modelValue', n);
};

// 根据qq获取用户信息 并更新 昵称 头像 邮箱
const handleGetInfoByQQ = () => {
  if (!props.modelValue.qq || nickNameLoading.value == true) return;
  nickNameLoading.value = true;
  getQQInfo({ qq: props.modelValue.qq, requestTimeout: 10000 })
    .then(res => {
      if (res.code == 200) {
        const n = {
          ...props.modelValue,
          email: res.data.email || props.modelValue.qq + '@qq.com',
          nickName: res.data.name || '',
          avatarUrl: getQQAvatar(props.modelValue.qq) || res.data.avatar
        };
        emits('update:modelValue', n);
        nickNameLoading.value = false;
      } else {
        nickNameLoading.value = false;
        const n = {
          ...props.modelValue,
          email: props.modelValue.qq == '37523953' ? 'snows_l@163.com' : props.modelValue.qq + '@qq.com',
          avatarUrl: getQQAvatar(props.modelValue.qq)
        };
        emits('update:modelValue', n);
      }
    })
    .catch(() => {
      nickNameLoading.value = false;
      const n = {
        ...props.modelValue,
        email: props.modelValue.qq == '37523953' ? 'snows_l@163.com' : props.modelValue.qq + '@qq.com',
        avatarUrl: getQQAvatar(props.modelValue.qq)
      };
      emits('update:modelValue', n);
    });
};

if (store.user && store.user.qq) {
  localValue.value.qq = store.user.qq || '';
  localValue.value.nickName = store.user.nickName || '';
  if (!localValue.value.nickName && localValue.value.qq) {
    handleGetInfoByQQ();
  }
  localValue.value.email = store.user.email || '';
  localValue.value.avatarUrl = store.user.avatarUrl || defaultAvatar;
  localValue.value.websiteUrl = store.user.websiteUrl || '';
  localValue.value.isPrivacy = store.user.isPrivacy || false;
  localValue.value.isEmailFeekback = store.user.isEmailFeekback || true;
}

//  提交
const handleSubmit = () => {
  if (localValue.value.submitLoading) return;
  if (!props.modelValue.value || !props.modelValue.qq || !props.modelValue.nickName) {
    isSubmit.value = true;
    CustomMessage({
      type: 'error',
      msg: '评论内容、QQ、昵称不能为空'
    });
  } else {
    const n = { ...props.modelValue, submitLoading: true };
    emits('update:modelValue', n);
    isSubmit.value = false;
    emits('submit', props.modelValue);
    store.SET_USER({ ...localValue.value });
  }
};
</script>

<style lang="scss" scoped>
.comment-wrap {
  width: 100%;
  padding: 20px;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-2);
  background-color: var(--bg-wrap-light-color-2);
  .top-tip {
    font-size: 14px;
    line-height: 24px;
    color: var(--text-color-2);
    margin-bottom: 14px;
  }
  .input-out-wrap {
    border-radius: var(--border-radius-2);
    background-color: var(--bg-content-color);
    .input-wrap {
      position: relative;
      padding: 20px 20px 10px 20px;
      border: 1px solid var(--text-color);
      background-image: url('@/assets/images/common/comment-bg.png');
      background-size: contain;
      background-repeat: no-repeat;
      background-position: right;
      resize: vertical;
      border-radius: var(--border-radius-2);
      &:focus-within {
        border-color: var(--theme-color);
      }
      &:hover {
        border-color: var(--theme-color);
        .have-text {
          + .input-label {
            border: 1px solid var(--theme-color) !important;
          }
        }
      }
      .input-text {
        width: calc(100% - 0px) !important;
        font-size: 14px;
        line-height: 22px;
        font-family: var(--font-family);
        border: none;
        background-color: transparent;
        outline: none;
        color: var(--text-color);
        &:focus {
          border-color: var(--theme-color);
          + .input-label {
            top: -8px;
            font-size: 12px;
            line-height: 14px;
            background-color: var(--input-label-bg-color);
            border-radius: 4px;
            border: 1px solid var(--theme-light-color-1) !important;
          }
        }
      }
      .have-text {
        + .input-label {
          top: -8px !important;
          font-size: 12px !important;
          line-height: 14px !important;
          background-color: var(--input-label-bg-color) !important;
          border-radius: 4px !important;
          border: 1px solid var(--text-color) !important;
        }
      }

      .input-label {
        position: absolute;
        left: 16px;
        top: 14px;
        padding: 0 6px;
        transform-origin: 0 0;
        pointer-events: none;
        transition: top 0.25s;
        color: var(--text-color);
      }
    }
  }
  .info-wrap {
    margin-top: 30px;
    padding: 20px 0;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    .input {
      width: 360px;
      padding: 5px 10px;
      background-color: var(--bg-content-color);
      position: relative;
      border: 1px solid var(--text-color);
      border-radius: var(--border-radius-2);
      margin-bottom: 40px;
      &:focus-within {
        border-color: var(--theme-color);
      }
      &:hover {
        border-color: var(--theme-color);
      }
      input {
        border: 0;
        outline: none;
        width: 100%;
        height: 30px;
        font-family: var(--font-family);
        font-size: 14px;
        border-radius: var(--border-radius-2);
        background-color: transparent;
        color: var(--text-color);
      }
      label {
        position: absolute;
        height: 18px;
        top: -20px;
        left: 5px;
        margin: 0 auto;
        font-size: 12px;
        font-weight: 400;
        color: var(--theme-light-color-3);
      }
    }
    .qq-wrap {
      position: relative;
    }
    .avatar {
      position: absolute;
      top: 5px;
      right: 10px;
      width: 30px;
      height: 30px;
      border-radius: 50%;
    }
  }
  .check-wrap {
    margin-top: -40px;
    display: flex;
    .check-item {
      min-width: 200px;
      display: flex;
      align-items: center;

      input[type='checkbox'] {
        position: relative;
        width: 18px;
        height: 18px;
        font-size: 12px;
      }

      input[type='checkbox']:checked {
        & + label {
          color: var(--theme-color);
        }
      }

      input[type='checkbox']:hover {
        &::after {
          border: 1px solid var(--theme-color);
        }
        & + label {
          color: var(--theme-color);
        }
      }

      input[type='checkbox']::after {
        cursor: url('@/assets/images/cursor/pointer.png'), auto !important; // clickable cursor to assets/images/cursor/pointer.png
        position: absolute;
        color: #000;
        width: 17px;
        height: 17px;
        display: inline-block;
        visibility: visible;
        padding-left: 0px;
        text-align: center;
        content: ' ';
        border-radius: 3px;
        border: 1px solid transparent;
      }

      input[type='checkbox']:checked::after {
        content: '✓';
        color: #fff;
        font-size: 12px;
        line-height: 20px;
        font-weight: bold;
        background-color: var(--theme-color);
      }

      label {
        color: var(--text-color);
        margin-left: 15px;
      }
      .privacy-tip {
        font-size: 12px;
        color: var(--theme-light-color-3);
      }
    }
  }
  .btn-wrap {
    margin-top: 60px;
    display: flex;
    justify-content: center;
    .btn {
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px solid var(--text-color);
      border-radius: var(--border-radius-2);
      width: 100%;
      max-width: 350px;
      line-height: 30px;
      text-align: center;
      height: 40px;
      padding: 5px 20px;
      border-radius: var(--border-radius-2);
      background-color: var(--bg-content-color);
      color: var(--text-color);
      transition: all 1s;
      &:hover {
        background-color: var(--theme-light-color-3);
        color: #fff;
        border: 1px solid var(--theme-color);
      }
    }
  }
}
.m-comment-wrap {
  padding: 10px !important;
  .check-wrap {
    justify-content: space-between;
    .check-item {
      min-width: 110px !important;
    }
  }

  .info-wrap {
    .input {
      width: 100%;
      margin-bottom: 40px;
      &:last-child {
        margin-bottom: 10px;
      }
    }
  }
  .check-wrap {
    margin: 10px 0;
  }
}
.is-submit {
  .no-input-wrap,
  .no-qq,
  .no-nick,
  .no-email {
    border: 1px solid red !important;
  }
}
</style>
